// 该属性用于隐藏对未使用代码的警告
#![allow(dead_code)]
// 创建一个 `enum`（枚举）来对 web 事件分类。注意变量名和类型共同指定了 `enum`
// 取值的种类：`PageLoad` 不等于 `PageUnload`，`KeyPress(char)` 不等于
// `Paste(String)`。各个取值不同，互相独立。
enum WebEvent {
    // 一个 `enum` 可以是单元结构体（称为 `unit-like` 或 `unit`），
    PageLoad,
    PageUnload,
    // 或者一个元组结构体，
    KeyPress(char),
    Paste(String),
    // 或者一个普通的结构体。
    Click { x: i64, y: i64 },
}
fn inspect(event: WebEvent) {
    match event {
        WebEvent::PageLoad => println!("page loaded"),
        WebEvent::PageUnload => println!("page unloaded"),
        WebEvent::KeyPress(c) => println!("pressed '{}'.", c),
        WebEvent::Paste(s) => println!("pasted \"{}\".", s),
        WebEvent::Click { x, y } => {
            println!("clicked at x={}, y={}.", x, y);
        }
    }
}
pub fn enumeration_test() {
    inspect(WebEvent::Click { x: 20, y: 80 });
    inspect(WebEvent::PageLoad);
    inspect(WebEvent::PageUnload);
    inspect(WebEvent::KeyPress('a'));
    // `to_owned()` 从一个字符串切片中创建一个具有所有权的 `String`。
    inspect(WebEvent::Paste("my text".to_owned()));
}
fn type_alias() {
    enum VeryVerboseEnumOfThingsToDoWithNumbers {
        Add,
        Subtract,
    }
    // 创建一个类型别名
    type Operations = VeryVerboseEnumOfThingsToDoWithNumbers;
    fn main() {
        // 我们可以通过别名引用每个枚举变量，避免使用又长又不方便的枚举名字
        let x = Operations::Add;
        
    }

    //最常见的情况就是在 impl 块中使用 Self 别名。
    impl VeryVerboseEnumOfThingsToDoWithNumbers {
        fn run(&self, x: i32, y: i32) -> i32 {
            match self {
                Self::Add => x + y,
                Self::Subtract => x - y,
            }
        }
    }
}
fn use_test() {
    use WebEvent::*;
    let event = Click { x: 30, y: 40 };
    match event {
        Click { x, y } => println!("{},{}", x, y),
        _ => println!(""),
    }
}
//enum 也可以像 C 语言风格的枚举类型那样使用。
fn c_style() {
    // 拥有隐式辨别值（implicit discriminator，从 0 开始）的 enum
    enum Number {
        Zero,
        One,
        Two,
    }
    // 拥有显式辨别值（explicit discriminator）的 enum
    enum Color {
        Red = 0xff0000,
        Green = 0x00ff00,
        Blue = 0x0000ff,
    }
    // `enum` 可以转成整型。
    println!("zero is {}", Number::Zero as i32);
    println!("violets are #{:06x}", Color::Blue as i32);
}
